package com.liangzong.betspider.utils;

import com.liangzong.betspider.command.GameOverStateCMD;
import com.liangzong.betspider.entity.TeamInfo;
import com.liangzong.betspider.command.AddTeamInfoCMD;
import com.liangzong.betspider.command.Command;
import com.liangzong.betspider.command.SyncTeamStateCMD;
import com.liangzong.betspider.enums.TeamStateEnum;
import com.liangzong.betspider.task.Process;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.util.BlockingArrayQueue;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;

import static com.liangzong.betspider.utils.ProcessDataUtil.calculateOverTime;

@Slf4j
public class SpiderInfoUtil {
    public static Map<String, TeamInfo> teamInfoMap = new ConcurrentHashMap<>();
    public static Map<String, String> timeInfoMap = new ConcurrentHashMap<>();
    public static BlockingQueue<Command> queue = new BlockingArrayQueue<>();
    public static Map<String, Integer> numOfElementsMap = new ConcurrentHashMap<>();
    public static List<Process> threads = new ArrayList<>();

    public static Map<String, Boolean> forceRefresh = new ConcurrentHashMap<>();

    public static void register2RefreshList(String sessionId) {
        forceRefresh.put(sessionId, false);
    }

    public static void clearRefreshList() {
        forceRefresh.clear();
    }

    public static void removeRefreshList(String sessionId) {
        forceRefresh.remove(sessionId);
    }

    public static boolean getRefreshState(String sessionId) {
        return forceRefresh.get(sessionId);
    }

    public static boolean updateRefreshStateSuccess(String sessionId) {
        return forceRefresh.put(sessionId, true);
    }


    public static void setRefreshState() {
        for (Iterator<String> iterator = forceRefresh.keySet().iterator(); iterator.hasNext(); ) {
            String next = iterator.next();
            forceRefresh.put(next, true);
        }
    }


    public static Map<String, LocalDateTime> taskSuccessInfoMap = new ConcurrentHashMap<>();

    public static boolean needToRefresh(String sessionId) {
        LocalDateTime lastTime = taskSuccessInfoMap.get(sessionId);
        if (lastTime == null) {
            return false;
        }
        LocalDateTime now = LocalDateTime.now();
        Duration duration = Duration.between(lastTime, now);
        long diff = duration.toSeconds();
        //大于一分钟 超时刷新界面
        if (diff > 60) {
            log.info("{} 大于一分钟没有获取到新数据超时刷新界面", sessionId);
            return true;
        }
        return false;
    }

    public static void putSuccessfulTime(String sessionId) {
        taskSuccessInfoMap.put(sessionId, LocalDateTime.now());
    }

    public static final String defaultNumOfElementKey = "MaxNum";

    public static synchronized void putNumOfElement(int num) {
//        Integer max = numOfElementsMap.get(defaultNumOfElementKey);
//        if(max == null){
//            numOfElementsMap.put(defaultNumOfElementKey,num);
//        }
//        if(num > max){
        numOfElementsMap.put(defaultNumOfElementKey, num);
//        }
    }

    public static Integer getMaxOfNum() {
       /* Collection<Integer> values = numOfElementsMap.values();
        Integer max= 0;
        for(  Iterator<Integer> it = values.iterator();it.hasNext();){
            Integer next = it.next();
            if(next > max){
                max = next;
            }
        }
        return max;*/
        if (numOfElementsMap.isEmpty()) {
            return 0;
        }
        return numOfElementsMap.get(defaultNumOfElementKey);
    }

    public static void resetMaxOfNum() {
        numOfElementsMap.put(defaultNumOfElementKey, 0);
    }

    public static void clearNumOfElement(String threadName, int num) {
        numOfElementsMap.clear();
    }

    public static TeamInfo getTeamInfo(String id) {
        return teamInfoMap.get(id);
    }

    public static void addPoint(String id, TeamInfo teamInfo, int overTime) {
        String time = teamInfo.getTime();
        if (time != null) {
            LocalDateTime overTimePoint = calculateOverTime(time, overTime);
            if (overTimePoint == null) {
                return;
            }
            teamInfo.setOverTime(overTimePoint);
        }
        if (teamInfo.isReady()) {
            log.info(teamInfo.toString());
            AddTeamInfoCMD command = new AddTeamInfoCMD();
            command.setTeamInfo(teamInfo);
            queue.add(command);
        }
        teamInfoMap.put(id, teamInfo);
    }

    public static void addGameOverTeam(String id, TeamInfo teamInfo) {
        log.info(teamInfo.toString());
        if (teamInfo.getState() == TeamStateEnum.GAMEOVER.getType()) {
            teamInfo.setState(TeamStateEnum.GAMEOVER.getType());
            GameOverStateCMD command = new GameOverStateCMD();
            command.setTeamInfo(teamInfo);
            queue.add(command);
        }
    }

    public static Command getData() {
        Command data = null;
        try {
            data = queue.poll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }


    public static Map<String, TeamInfo> getAllTeamInfoMap() {
        return teamInfoMap;
    }

    public static String getTimeInfo(String key) {
        return timeInfoMap.get(key);
    }

    //放入最新的时间
    public static void putTimeInfo(String key, String value) {
        if (StringUtils.isEmpty(value)) {
            return;
        }
        timeInfoMap.put(key, value);
    }

    public static void clearTimeInfo() {
        List<String> collect = new ArrayList<>();

        //清理超时数据
        Collection<TeamInfo> values = teamInfoMap.values();
        LocalDateTime now = LocalDateTime.now();
        for (Iterator<TeamInfo> it = values.iterator(); it.hasNext(); ) {
            TeamInfo teamInfo = it.next();
            LocalDateTime overTime = teamInfo.getOverTime();
            if (overTime != null && overTime.isBefore(now)) {
                //超时更新
                if (teamInfo.getUrl() != null) {
                    collect.add(teamInfo.getUrl());
                }
                //删除时间 半小时后再清理缓存数据
                LocalDateTime delTime = overTime.plusMinutes(30);
                if (delTime.isBefore(now)) {
                    if (teamInfo.getId() != null) {
                        teamInfoMap.remove(teamInfo.getId());
                    }
                    if (teamInfo.getUrl() != null) {
                        timeInfoMap.remove(teamInfo.getUrl());
                    }
                }
            }
        }
        SyncTeamStateCMD command = new SyncTeamStateCMD();
        command.setSyncInfoList(collect);
        queue.add(command);
    }

}
